package org.sdnstproject.interlayer.OF10Protocal;

import org.projectfloodlight.openflow.types.MacAddress;
import org.projectfloodlight.openflow.types.U16;
import org.projectfloodlight.openflow.types.U32;
import org.sdnstproject.interlayer.utils.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

/*01 0c 0040 00000000 0200000000000000 fffe 26a92064cc4b  73310000000000000000000000000000 00000001 00000001 00000000 00000000 00000000 00000000
 * OFPortStatus默认值:OFPortStatusVer10(xid=0, reason=MODIFY, 
 * desc=OFPortDescVer10(portNo=local, hwAddr=26:a9:20:64:cc:4b, name=s1, 
 * config=[PORT_DOWN], state=[LINK_DOWN, STP_LISTEN], curr=[], advertised=[], 
 * supported=[], peer=[]))
 * */

/**{@code FuPortStatus}:FuPortStatus消息类，功能:根据byte数组构造FuPortStatus消息对象，即：解析FuPortStatus、
 * 默认构造FuPortStatus消息、任意设置修改字段值等.
 * */
public class FuPortStatusV10 {
	private static final Logger log = LoggerFactory.getLogger(FuPortStatusV10.class);
    /**version 类型:byte 默认值: 1.0*/
    public byte version = 1;
    /**type 类型:byte 默认值: 12*/
    public byte type = 12;
    /**length 类型:short 默认值: 64*/
    public short length = 64;
    /**xid 类型:long 默认值: 0x0L*/
    public long xid = 0x0L;
    /**reason 类型:byte 默认值: 1*/
    public byte reason = 1;
    public int portNo = 0xFFffFFfe;
    public long hwAddr = 0x26a92064cc4bL;
    public String name = "s1";
    public int config = 1;
    public int state = 1;
    public int curr = 0;
    public int advertised = 0;
    public int supported = 0;
    public int peer = 0;

    public FuPortStatusV10() {
    	
    }
    
    public FuPortStatusV10 setXid(long xid) {
		this.xid = xid;
		return this;
	}
    
    public FuPortStatusV10 setField(String field, String value) throws NumberFormatException{
    	switch (field) {
			case "version":
				this.version =Byte.parseByte(value);
				break;
			case "type":
				this.type = Byte.parseByte(value);
				break;
			case "length":
				this.length = Short.parseShort(value);
				break;
			case "xid":
				this.xid = Long.parseLong(value);
				break;
			case "reason":
				this.reason = Byte.parseByte(value);
				break;
			case "portNo":
				this.portNo = Integer.parseInt(value);
				break;
			case "hwAddr":
				this.hwAddr = Long.parseLong(value);
				break;
			case "name":
				this.name = value;
				break;
			case "config":
				this.config = Integer.parseInt(value);
				break;
			case "state":
				this.state = Integer.parseInt(value);
				break;
			case "curr":
				this.curr = Integer.parseInt(value);
				break;
			case "advertised":
				this.advertised = Integer.parseInt(value);
				break;
			case "supported":
				this.supported = Integer.parseInt(value);
				break;
			case "peer":
				this.peer = Integer.parseInt(value);
				break;
		}
    	return this;
    }
    
    public MacAddress gethwAddrObject(long hwAddr) {
		return MacAddress.of(hwAddr);
	}
	
	public ByteBuf writeTo() {
		ByteBuf bb = Unpooled.directBuffer();
        // fixed value property version = 1
        bb.writeByte(this.version);
        // fixed value property type = 12
        bb.writeByte((byte) 0xc);
        // fixed value property length = 64
        bb.writeShort(this.length);
        bb.writeInt(U32.t(this.xid));
        bb.writeByte(this.reason);
        // pad: 7 bytes
        bb.writeZero(7);
        bb.writeShort(U16.t(portNo));
        this.gethwAddrObject(this.hwAddr).write6Bytes(bb);
        Utils.writeFixedLengthString(bb, this.name, 16);
        bb.writeInt(config);
        bb.writeInt(state);
        bb.writeInt(curr);
        bb.writeInt(advertised);
        bb.writeInt(supported);
        bb.writeInt(peer);
        return bb;
    }
	
	@Override
    public String toString() {
        StringBuilder b = new StringBuilder("OFPortStatusVer10(");
        b.append("version=").append(version);
        b.append(", ");
        b.append("type=").append(type);
        b.append(", ");
        b.append("length=").append(length);
        b.append(", ");
        b.append("xid=").append(xid);
        b.append(", ");
        b.append("reason=").append(reason);
        b.append(", ");
        b.append("portNo=").append(portNo);
        b.append(", ");
        b.append("hwAddr=").append(hwAddr);
        b.append(", ");
        b.append("name=").append(name);
        b.append(", ");
        b.append("config=").append(config);
        b.append(", ");
        b.append("state=").append(state);
        b.append(", ");
        b.append("curr=").append(curr);
        b.append(", ");
        b.append("advertised=").append(advertised);
        b.append(", ");
        b.append("supported=").append(supported);
        b.append(", ");
        b.append("peer=").append(peer);
        b.append(")");
        return b.toString();
    }

}
